﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

/// <summary>
/// 对象池工厂，创建和管理对象池,可以依附于任何一个管理器进行实例化
/// </summary>
public class PoolFactory
{

    public PoolFactory(Transform root, string resourceRootPath = "")
    {
        this.parent = root;
        this.prefabRootPath = resourceRootPath;
    }
    
    
    public Dictionary<string, BhvEasyPool> pools = new Dictionary<string, BhvEasyPool>();
    public string prefabRootPath = "";

    
    public Transform parent;

    public void ClearAll()
    {
        //清除所有残留对象
        foreach (var item in pools)
        {
            item.Value.ClearAll();
        }
    }

    public void Clear(string name)
    {
        //清除所有残留对象
        foreach (var item in pools)
        {
            if (item.Key == name)
            {
                item.Value.ClearAll();
                pools.Remove(name);
                break;
            }
        }
    }
    
    public void PutGameObject(GameObject obj, string name)
    {
        GetPool(name)?.Put(obj);
    }

    
    
    
    /// <summary>
    /// 创建特效对象池
    /// </summary>
    /// <param name="poolName"></param>
    /// <param name="initCacheSize"></param>
    /// <returns></returns>
    public BhvEasyPool CreatePool(string poolName,GameObject prefab, int initCacheSize = 3)
    {
        if (pools.ContainsKey(poolName))
        {
            Debug.Log(poolName + " 对象池已生成，请勿重复创建");
            return pools[poolName];
        }
        
        if (prefab)
        {
            var gameObject = new GameObject();
            gameObject.name = poolName;
            gameObject.SetActive(false);
            gameObject.transform.parent = this.parent;
            var pool = gameObject.AddComponent<BhvEasyPool>();
            pool.cloneObject = prefab;
            // print("add:" + pool.cloneObject.name);
            pool.initCacheSize = initCacheSize;
            pools.Add(poolName, pool);
            gameObject.SetActive(true);
            return pool;
        }
        return null;
    }
    
    
    
    /// <summary>
    /// 创建特效对象池
    /// </summary>
    /// <param name="poolName"></param>
    /// <param name="initCacheSize"></param>
    /// <returns></returns>
    public BhvEasyPool CreatePool(string poolName, int initCacheSize = 3)
    {
        if (pools.ContainsKey(poolName))
        {
            Debug.Log(poolName + " 对象池已生成，请勿重复创建");
            return pools[poolName];
        }

        // var prefab = effectConfig.Particles.Where(data => data.name == poolName)?.FirstOrDefault();
        var prefab = Resources.Load<GameObject>(this.prefabRootPath + "/" + poolName);
        if (prefab)
        {
            var gameObject = new GameObject();
            gameObject.name = poolName;
            gameObject.SetActive(false);
            gameObject.transform.parent = this.parent;
            var pool = gameObject.AddComponent<BhvEasyPool>();
            pool.cloneObject = prefab;
            // print("add:" + pool.cloneObject.name);
            pool.initCacheSize = initCacheSize;
            pools.Add(poolName, pool);
            gameObject.SetActive(true);
            return pool;
        }
        else
        {
            Debug.LogWarning(poolName + " 对象池创建失败，不存在路径:" + this.prefabRootPath + "/" + poolName);
        }
        return null;
    }

    public BhvEasyPool GetPool(string poolName)
    {
        BhvEasyPool pool = null;
        if (pools.ContainsKey(poolName))
        {
            pool = pools[poolName];
        }
        else
        {
            pool = CreatePool(poolName, 3);
        }

        return pool;
    }

    public GameObject GetObjectFromPool(string poolName, int cacheMax = 0)
    {
        BhvEasyPool pool;

        if (pools.ContainsKey(poolName))
        {
            pool = pools[poolName];
        }
        else
        {
            pool = CreatePool(poolName, 3);
        }


        if (pool)
        {
            //对象池空了，并且缓存数量超过上限值,则不在扩容
            if (cacheMax != 0 && pool.stack.Count <= 0 && pool.cacheCount > cacheMax)
            {
                return null;
            }
            else
            {
                return pool.Get();
            }
        }
        return null;
    }

}
